package yl.hs.bmipfull.service.system.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.daos.system.*;
import yl.hs.bmipfull.pojo.system.*;
import yl.hs.bmipfull.service.system.IMenuInfoService;
import yl.hs.bmipfull.utils.CK;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.HsApp;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.SubmitModel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 张凯 on 2021/5/10 <br/>
 */
@Service
public class MenuInfoServiceImpl extends SystemBaseService implements IMenuInfoService {

    @Autowired
    IMenuButtonDao buttonDao;
    @Autowired
    private IMenuInfoDao menuInfoDao;

    @Autowired
    IAppSettingDao settingDao;

    @Autowired
    ICoreDataTagDao tagDao;

    @Autowired
    IRoleInfoDao roleDao;

    @Autowired
    IAuthorizeDao authorizeDao;

    @Override
    public List<MenuInfoEntity> queryList(PageQuery pageQuery) throws Exception {
        pageQuery.checkSortSides(MenuInfoEntity.class);
        return menuInfoDao.queryList(pageQuery.getQuery());
    }

    @Override
    public MenuInfoEntity findBySn(String sn) {
        return menuInfoDao.findBySN(sn);
    }

    @Override
    public List<MenuInfoEntity> queryByParentSn(String parentSn) {
        return menuInfoDao.queryByParentSn(parentSn);
    }

    @Transactional
    public Integer saveMenu(SubmitModel submitModel) throws Exception {
        Integer result = 0;
        MenuInfoEntity entity = new MenuInfoEntity();
        if (Tl.isEmpty(submitModel.getSn())) {
            //执行保存
            Tl.getChangeLog(entity, submitModel.getData());
            entity.setPYFieldValue();
            entity.setSn(queryNewSN(MenuInfoEntity.class));
            entity.setParent(menuInfoDao.findBySN(entity.getParentSN()));
            result = menuInfoDao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "插入系统菜单信息", Tl.toJson(entity), MenuInfoEntity.class);
            }

        } else {
            //执行修改
            entity = menuInfoDao.findBySN(submitModel.getSn());
            var backJson = entity.toJson();
            var changeLog = Tl.getChangeLog(entity, submitModel.getData());
            entity.setPYFieldValue();
            entity.setParent(menuInfoDao.findBySN(entity.getParentSN()));
            result = menuInfoDao.update(entity);
            if (result > 0) {
                writeLog(ActionType.UPDATE, submitModel.getSn(), changeLog, backJson, MenuInfoEntity.class);
            }
        }
        return result;
    }

    @Transactional
    public Integer delete(String[] sn) {
        var result = menuInfoDao.changeStateBySn(sn, DataState.DELETED.code);
        if (result > 0) {
            writeLog(ActionType.DELETE, sn, MenuInfoEntity.class);
        }
        return result;
    }

    @Override
    public List<Object> queryPermissionTree() {
        var user = HsApp.getCurrent();
        List<MenuInfoEntity> allMenuList = new ArrayList<>();
        if (user.getAccount().equals(HsApp.getSystemSet(CK.SupperAdminKey))) {
            allMenuList = menuInfoDao.queryAllMenus(HsApp.getSystemSet(CK.SysVersion));
        } else {
            var userRoles = tagDao.queryByMainSn(user.getUserSN(), Tl.getDBMapCode(RoleInfoEntity.class));
            var userRoleSnArray = userRoles.stream().map(CoreDataTagEntity::getTagSN).collect(Collectors.toList());

            if (userRoleSnArray!= null && userRoleSnArray.size() > 0) {
                var authorizes = authorizeDao.queryByOwnerSN(userRoleSnArray.toArray(new String[userRoleSnArray.size()]));
               var authorSNList = authorizes.stream().map(AuthorizeInfoEntity::getFeatureSN).distinct().collect(Collectors.toList());
               var sAll = menuInfoDao.queryAllMenus(HsApp.getSystemSet(CK.SysVersion));
               allMenuList = sAll.stream().filter(t->authorSNList.contains(t.getSn())).toList();
            }
        }

        var allButtonList = buttonDao.queryAllButtons();
        return generateTree(allMenuList, allButtonList, null);
    }


    private List<Object> generateTree(List<MenuInfoEntity> allMenus, List<MenuButtonEntity> allButtons, String parentSN) {
        List<MenuInfoEntity> nodes = new ArrayList<>();
        List<MenuButtonEntity> buttons = new ArrayList<>();
        if (Tl.isEmpty(parentSN)) {
            nodes.addAll(allMenus.stream().filter(t->t.getLayer() == 0).collect(Collectors.toList()));
        } else {
            nodes.addAll(allMenus.stream().filter(t -> t.getParentSN() != null && parentSN.equals(t.getParentSN())).collect(Collectors.toList()));
            buttons.addAll(allButtons.stream().filter(t -> t.getMenuSN() != null && parentSN.equals(t.getMenuSN())).collect(Collectors.toList()));
        }
        var list = new ArrayList<Object>();
        if (nodes.size() > 0) {
            for (var item : nodes) {
                var map = new HashMap<String, Object>();
                map.put("id", item.getSn());
                map.put("name", item.getFullName());
                map.put("type", "menu");
                map.put("children", generateTree(allMenus, allButtons, item.getSn()));
                list.add(map);
            }
        }
        if (buttons.size() > 0) {
            for (var item : buttons) {
                var map = new HashMap<String, Object>();
                map.put("id", item.getSn());
                map.put("name", item.getFullName());
                map.put("type", "button");
                list.add(map);
            }
        }
        return list;
    }
}
